﻿using System.Collections.Generic;
using UnityEngine;

public class ChineseRestaurantManager : MonoSingleton<ChineseRestaurantManager> {
    public enum LevelName {
        Level_1,
        Level_2,
    }

    public DishName currentDishName;
    public LevelName currentLevelName;
    public Transform currentLevelRoot;
    public RoleName currentRoleName;

    public System.Action<bool> onClickSwitch;

    PhysicMaterial _physicMat;

    public PhysicMaterial PhysicMat {
        get {
            if (_physicMat == null) {
                _physicMat = new PhysicMaterial();
                _physicMat.dynamicFriction = 0.01f;
                _physicMat.staticFriction = 0.1f;
            }

            return _physicMat;
        }
    }

    List<FloaterByPhysics> _floaterList = new List<FloaterByPhysics>();

    public List<FloaterByPhysics> FloaterList {
        get {
            return _floaterList;
        }
    }

    protected override void Awake() {
        base.Awake();
        PlayBGM();

        if (currentLevelRoot == null) {
            LoadLevel(currentLevelName);

            if (currentLevelName == LevelName.Level_1) {
                currentLevelRoot.GetComponent<LevelFirst>().Forward();
            }
        } else if (currentLevelRoot.name == LevelName.Level_1.ToString()) {
            currentLevelRoot.GetComponent<LevelFirst>().Forward();
        }
    }

    protected override void OnDestroy() {
        if (AudioManager.HasInstance()) {
            AudioManager.Instance.BackgroundMusicVolume = 1f;
        }

        Clear();
        base.OnDestroy();
    }

    public void PlayBGM() {
        AudioManager.Instance.PlayMusic(ChineseRestaurantResPath.SFX_BGM, true, true);
        AudioManager.Instance.BackgroundMusicVolume = 0.5f;
    }

    public void PauseBGM() {
        AudioManager.Instance.PauseBackgroudMusic();
    }

    public void StopBGM() {
        AudioManager.Instance.StopBackgroundMusic();
    }

    public void EnableFloater(bool isEnabled) {
        for (var i = 0; i < Instance.FloaterList.Count; i++) {
            Instance.FloaterList[i].enabled = isEnabled;
        }
    }

    public void RestoreFriction() {
        PhysicMat.dynamicFriction = 0.01f;
        PhysicMat.staticFriction = 0.1f;
    }

    public void CancelFriction() {
        PhysicMat.dynamicFriction = 0f;
        PhysicMat.staticFriction = 0f;
    }

    public void ToNextLevel() { 
        TransitionManager.Instance.StartTransition(
            () => {
                PauseBGM();

                switch (currentLevelName) {
                    case LevelName.Level_1:
                        LoadLevel(LevelName.Level_2);
                        break;
                    case LevelName.Level_2:
                        LoadLevel(LevelName.Level_1);
                        currentLevelRoot.GetComponent<LevelFirst>().Reverse();
                        FloaterList.Clear();
                        break;
                }
            },
            () => {
                PlayBGM();
            });
    }

    bool _isHandling = false;

    public void ToLastLevel() {
        if (_isHandling) {
            return;
        }

        _isHandling = true;
        AudioManager.Instance.StopAllSound();

        switch (currentLevelName) {
            case LevelName.Level_1:
                OnExit();
                break;
            default:
                LoadLevel(LevelName.Level_1);
                currentLevelRoot.GetComponent<LevelFirst>().Forward();

                if (TargetSlicer.HasInstance()) {
                    TargetSlicer.DestroyInstance();
                }

                Destroy(TurboSlice.instance.gameObject);
                break;
        }

        StartCoroutine(TimeUtility.DelayInvoke(1f, () => _isHandling = false));
    }

    public void OnExit() {
        GameLogic.DestroyInstance();
        GameStateManager.Instance.GotoState(GameStateName.MAIN_STATE);
    }

    void Clear() {
        if (currentLevelRoot) {
            if (Application.isEditor) {
                DestroyImmediate(currentLevelRoot.gameObject);
            } else {
                Destroy(currentLevelRoot.gameObject);
            }
            
            Resources.UnloadUnusedAssets();
            System.GC.Collect();
        }
    }

    public void LoadLevel(LevelName levelName) {
        Clear();
        currentLevelName = levelName;
        currentLevelRoot = CommonUtility.InstantiateFrom(ChineseRestaurantResPath.PREFAB_DIR + levelName.ToString(), null);
    }

    public FoodName[] GetFoodMaterialFromCurrentDishName() {
        return GetFoodMaterialFrom(currentDishName);
    }

    public FoodName[] GetFoodMaterialFrom(DishName dishName) {
        switch (dishName) {
            case DishName.DongPoRou:
                return new FoodName[] { FoodName.Pork, FoodName.GreenVegetable };
            case DishName.HongShaoYu:
                return new FoodName[] { FoodName.Fish };
            case DishName.HuangGuaHuoTui:
                return new FoodName[] { FoodName.Cucumber, FoodName.Ham };
            case DishName.QingChaoXiaRen:
                return new FoodName[] { FoodName.Shrimp, FoodName.Carrot };
            case DishName.QingJiaoPeiGen:
                return new FoodName[] { FoodName.GreenPepper, FoodName.Bacon };
            case DishName.QingCaiDouFuTang:
                return new FoodName[] { FoodName.Tofu, FoodName.GreenVegetable, FoodName.Shiitake };
            default:
                return new FoodName[] { };
        }
    }

    public string GetSpriteNameFrom(FoodName foodName) {
        switch (foodName) {
            case FoodName.Shrimp:
                return "zct_icon01";
            case FoodName.GreenVegetable:
                return "zct_icon02";
            case FoodName.Cucumber:
                return "zct_icon03";
            case FoodName.Pork:
                return "zct_icon04";
            case FoodName.Fish:
                return "zct_icon05";
            case FoodName.GreenPepper:
                return "zct_icon06";
            case FoodName.Tofu:
                return "zct_icon07";
            case FoodName.Carrot:
                return "zct_icon08";
            case FoodName.Shiitake:
                return "zct_icon09";
            case FoodName.Ham:
                return "zct_icon10";
            case FoodName.Bacon:
                return "zct_icon11";
            default:
                return "";
        }
    }

    public FoodName GetFoodNameFrom(string spriteName) {
        switch (spriteName) {
            case "zct_icon01":
                return FoodName.Shrimp;
            case "zct_icon02":
                return FoodName.GreenVegetable;
            case "zct_icon03":
                return FoodName.Cucumber;
            case "zct_icon04":
                return FoodName.Pork;
            case "zct_icon05":
                return FoodName.Fish;
            case "zct_icon06":
                return FoodName.GreenPepper;
            case "zct_icon07":
                return FoodName.Tofu;
            case "zct_icon08":
                return FoodName.Carrot;
            case "zct_icon09":
                return FoodName.Shiitake;
            case "zct_icon10":
                return FoodName.Ham;
            case "zct_icon11":
                return FoodName.Bacon;
            default:
                return default(FoodName);
        }
    }

    public string GetVoicePathFrom(FoodName foodName) {
        switch (foodName) {
            case FoodName.Shrimp:
                return ChineseRestaurantResPath.VOICE_FOOD_NAME_SHRIMP;
            case FoodName.GreenVegetable:
                return ChineseRestaurantResPath.VOICE_FOOD_NAME_GREEN_VEGETABLE;
            case FoodName.Cucumber:
                return ChineseRestaurantResPath.VOICE_FOOD_NAME_CUCUMBER;
            case FoodName.Pork:
                return ChineseRestaurantResPath.VOICE_FOOD_NAME_PORK;
            case FoodName.Fish:
                return ChineseRestaurantResPath.VOICE_FOOD_NAME_FISH;
            case FoodName.GreenPepper:
                return ChineseRestaurantResPath.VOICE_FOOD_NAME_GREEN_PEPPER;
            case FoodName.Tofu:
                return ChineseRestaurantResPath.VOICE_FOOD_NAME_TOFU;
            case FoodName.Carrot:
                return ChineseRestaurantResPath.VOICE_FOOD_NAME_CARROT;
            case FoodName.Shiitake:
                return ChineseRestaurantResPath.VOICE_FOOD_NAME_SHIITAKE;
            case FoodName.Ham:
                return ChineseRestaurantResPath.VOICE_FOOD_NAME_HAM;
            case FoodName.Bacon:
                return ChineseRestaurantResPath.VOICE_FOOD_NAME_BACON;
            default:
                return "";
        }
    }

    public string GetVoicePathFrom(CondimentName name) {
        switch (name) {
            case CondimentName.Chicken:
                return ChineseRestaurantResPath.VOICE_CONDIMENT_CHICKEN;
            case CondimentName.Sauce:
                return ChineseRestaurantResPath.VOICE_CONDIMENT_SAUCE;
            case CondimentName.Salt:
                return ChineseRestaurantResPath.VOICE_CONDIMENT_SALT;
            case CondimentName.Garlic:
                return ChineseRestaurantResPath.VOICE_CONDIMENT_GARLIC;
            case CondimentName.Shallot:
                return ChineseRestaurantResPath.VOICE_CONDIMENT_SHALLOT;
            case CondimentName.Pepper:
                return ChineseRestaurantResPath.VOICE_CONDIMENT_PEPPER;
            default:
                return "";
        }
    }

    public string GetVoicePathFrom(RoleState state) {
        switch (state) {
            case RoleState.OrderDishes:
                string[] voicePaths = null;

                if (currentRoleName == RoleName.AiSha) {
                    voicePaths = new string[] { ChineseRestaurantResPath.AISHA_404040407, ChineseRestaurantResPath.AISHA_404040418 };
                } else if (currentRoleName == RoleName.AJiaSi) {
                    voicePaths = new string[] { ChineseRestaurantResPath.AJIASI_404040412, ChineseRestaurantResPath.AJIASI_404040422, ChineseRestaurantResPath.AJIASI_404040423 };
                } else if (currentRoleName == RoleName.NuoWa) {
                    voicePaths = new string[] { ChineseRestaurantResPath.NUOWA_404040410, ChineseRestaurantResPath.NUOWA_404040413 };
                }

                return voicePaths[Random.Range(0, voicePaths.Length)];
            case RoleState.ServingDishes:
                if (currentRoleName == RoleName.AiSha) {
                    var voices = new string[] { ChineseRestaurantResPath.AISHA_404040404, ChineseRestaurantResPath.AISHA_404040419 };
                    return voices[Random.Range(0, voices.Length)];
                } else if (currentRoleName == RoleName.AJiaSi) {
                    return ChineseRestaurantResPath.AJIASI_404040401;
                } else if (currentRoleName == RoleName.NuoWa) {
                    var voices = new string[] { ChineseRestaurantResPath.NUOWA_404040411, ChineseRestaurantResPath.NUOWA_404040414 };
                    return voices[Random.Range(0, voices.Length)];
                }
                break;
            case RoleState.EatUpDishes:
                string[] paths = null;

                if (currentRoleName == RoleName.AiSha) {
                    paths = new string[] { ChineseRestaurantResPath.AISHA_404040405, ChineseRestaurantResPath.AISHA_404040406, ChineseRestaurantResPath.AISHA_404040421 };
                } else if (currentRoleName == RoleName.AJiaSi) {
                    paths = new string[] { ChineseRestaurantResPath.AJIASI_404040402, ChineseRestaurantResPath.AJIASI_404040403, ChineseRestaurantResPath.AJIASI_404040425 };
                } else if (currentRoleName == RoleName.NuoWa) {
                    paths = new string[] { ChineseRestaurantResPath.NUOWA_404040408, ChineseRestaurantResPath.NUOWA_404040409, ChineseRestaurantResPath.NUOWA_404040417 };
                }

                return paths[Random.Range(0, paths.Length)];
        }

        return "";
    }
}
